package de.slothsoft.commons.swing;

import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JTable;

import de.slothsoft.commons.swing.ITableButtonListener.TableButtonEvent;

public class JTableButtonMouseListener extends MouseAdapter {

	public static final JTableButtonMouseListener add(JTable table,
			ITableButtonListener... listeners) {
		JTableButtonMouseListener listener;
		listener = new JTableButtonMouseListener(table);
		table.addMouseListener(listener);

		if (listeners != null) {
			for (ITableButtonListener l : listeners)
				listener.addListener(l);
		}

		return listener;
	}

	private JTable table;
	private List<ITableButtonListener> listeners = new ArrayList<ITableButtonListener>();

	public JTableButtonMouseListener(JTable table) {
		this.table = table;
	}

	public void addListener(ITableButtonListener listener) {
		this.listeners.add(listener);
	}

	public void removeListener(ITableButtonListener listener) {
		this.listeners.remove(listener);
	}

	private void forwardEventToButton(MouseEvent e) {
		int row = this.table.rowAtPoint(e.getPoint());
		int column = this.table.columnAtPoint(e.getPoint());

		if (row >= this.table.getRowCount() || row < 0
				|| column >= this.table.getColumnCount() || column < 0)
			return;

		Rectangle rect = this.table.getCellRect(row, column, true);

		int x = e.getX() - rect.x;
		int y = e.getY() - rect.y;

		TableButtonEvent event = new TableButtonEvent(row, column, x, y);
		fireActionPerformed(event);

		this.table.repaint();
	}

	protected void fireActionPerformed(TableButtonEvent event) {
		ITableButtonListener[] listenersArray = this.listeners
				.toArray(new ITableButtonListener[0]);
		for (ITableButtonListener listener : listenersArray) {
			listener.actionPerformed(event);
		}

	}

	@Override
	public void mouseClicked(MouseEvent e) {
		forwardEventToButton(e);
	}

	@Override
	public void mousePressed(MouseEvent e) {
		forwardEventToButton(e);
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		forwardEventToButton(e);
	}

	@Override
	public void mouseMoved(MouseEvent e) {
		MouseEvent enteredEvent = new MouseEvent(e.getComponent(),
				MouseEvent.MOUSE_ENTERED, e.getWhen(), e.getModifiers(),
				e.getX(), e.getY(), e.getClickCount(), e.isPopupTrigger(),
				e.getButton());
		forwardEventToButton(enteredEvent);
	}
}